import math
import pyclipper

from ClipperAdaptor import ClipperAdaptor
from PolyPcrseeker import seekPolyPcr
from Polyline import Polyline


class GenCpPath:
    def __init__(self, boundaries, interval, shellThk):
        self.boundaries = boundaries
        self.interval = interval
        self.shellThk = shellThk
        self.arcTolerance = 0.005
        self.jointType = pyclipper.JT_SQUARE
        self.offsetPolyses = []
        self.paths = []
        self.offset()
        self.linkLocalOffsets()

    def offset(self):
        ca = ClipperAdaptor()
        ca.arcTolerance = self.arcTolerance
        delta = self.interval / 2
        polys = ca.offset(self.boundaries, -delta, self.jointType)
        self.offsetPolyses.append(polys)
        while math.fabs(delta) < self.shellThk:
            delta += self.interval
            polys = ca.offset(self.boundaries, -delta, self.jointType)
            if not polys or len(polys) == 0:
                break
            self.offsetPolyses.append(polys)

    def linkToParent(self, child):
        parent = child.parent
        pt = child.startPoint()
        dMin, iAtdMin = float("inf"), 0
        for i in range(parent.count()):
            d = pt.distanceSquare(parent.points[i])
            if d < dMin:
                dMin, iAtdMin = d, i
        newPoly = Polyline()
        for i in range(iAtdMin + 1):
            newPoly.addPoint(parent.points[i].clone())
        newPoly.endPoint().w = 2
        for i in range(child.count()):
            newPoly.addPoint(child.points[i].clone())
        newPoly.endPoint().w = 2
        for i in range(iAtdMin, parent.count(), 1):
            newPoly.addPoint(parent.points[i].clone())
        return newPoly

    def findParent(self):
        polys = seekPolyPcr(self.offsetPolyses)
        if polys:
            self.offsetPolyses = polys
            return True
        return False

    def linkLocalOffsets(self):
        self.findParent()
        for i in range(len(self.offsetPolyses) - 1, 0, -1):
            childs = self.offsetPolyses[i].childs
            for j in range(len(childs) - 1, -1, -1):
                child = childs[j]
                newpoly = self.linkToParent(child)
                parent = child.parent
                parent.points = newpoly.points
                del childs[j]
        for path in self.offsetPolyses:
            self.paths.append(path)
        self.offsetPolyses.clear()


def genCpPath(boundaries, interval, shellThk):
    return GenCpPath(boundaries, interval, shellThk).paths
